package at.ac.univie.zsu.aguataplan.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

/**
 * generic dao to access datasource
 * 
 * @author gerry
 * 
 */
@Repository
public class DaoBean implements Dao {
	@PersistenceContext
	transient EntityManager em;

	// ----------------------------------------------------
	// CONSTRUCTOR
	// ----------------------------------------------------
	public DaoBean() {

	}

	// ----------------------------------------------------
	// METHODS
	// ----------------------------------------------------

	@Transactional
	public <T> void clearTable(Class<T> c) {
		this.em.createQuery("DELETE FROM " + c.getName()).executeUpdate();
		em.flush();
	}

	@Transactional
	public void persist(Object o) throws Exception {
		em.persist(o);
		em.flush();

	}

	public <T> T find(Class<T> c, Long id) throws Exception {
		return em.find(c, id);
	}

	public <T> List<T> findAll(Class<T> c) throws Exception {
		return em.createQuery("SELECT o FROM " + c.getName() + " o", c).getResultList();
	}

	@Transactional
	public <T> void remove(Class<T> t, long id) throws Exception {
		T tt = find(t, id);
		if (em.contains(tt)) {
			em.remove(tt);
			em.flush();
		}
	}

	@Transactional
	public void flush() throws Exception {
		em.flush();
	}

	@Transactional
	public void clear() throws Exception {
		em.clear();
		em.flush();
	}

	public <T> long count(Class<T> c) throws Exception {
		return em.createQuery("SELECT COUNT(o) FROM " + c.getName() + " o", Long.class).getSingleResult();
	}

	@Transactional
	public <T> T merge(T c) throws Exception {
		T merged = em.merge(c);
		em.flush();
		return merged;
	}

	// --------

	public <T> List<T> findEntries(Class<T> c, int firstResult, int maxResults) {
		return em.createQuery("SELECT o FROM " + c.getName() + " o", c).setFirstResult(firstResult)
				.setMaxResults(maxResults).getResultList();
	}
}
